<?php

namespace app\admin\controller;

use think\Controller;
use think\Db;
use think\Request;

/**
 * 管理员认证控制器
 */
class Auth extends Controller
{
    /**
     * 管理员登录
     */
    public function login()
    {
        if ($this->request->isPost()) {
            $username = input('post.username', '');
            $password = input('post.password', '');

            // 验证参数
            if (empty($username) || empty($password)) {
                return json(['code' => 1, 'msg' => '用户名和密码不能为空']);
            }

            try {
                // 查找管理员
                $admin = Db::name('users')
                    ->where('username', $username)
                    ->where('status', 1)
                    ->find();

                if (!$admin) {
                    $this->logLoginAttempt($username, 0, '用户不存在或已被禁用');
                    return json(['code' => 1, 'msg' => '用户名或密码错误']);
                }

                // 验证密码
                if (md5($password) !== $admin['password']) {
                    $this->logLoginAttempt($username, 0, '密码错误', $admin['id']);
                    return json(['code' => 1, 'msg' => '用户名或密码错误']);
                }

                // 生成会话令牌
                $token = $this->generateToken();
                $expiresAt = date('Y-m-d H:i:s', time() + 7200); // 2小时过期

                // 存储会话
                Db::name('sessions')->insert([
                    'admin_id' => $admin['id'],
                    'token' => $token,
                    'expires_at' => $expiresAt,
                    'ip_address' => $this->request->ip(),
                    'user_agent' => $this->request->header('User-Agent', ''),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

                // 更新管理员登录信息
                Db::name('users')->where('id', $admin['id'])->update([
                    'last_login_time' => date('Y-m-d H:i:s'),
                    'last_login_ip' => $this->request->ip(),
                    'login_count' => $admin['login_count'] + 1,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

                // 记录登录日志
                $this->logLoginAttempt($username, 1, '登录成功', $admin['id']);

                // 清理过期会话
                $this->cleanExpiredSessions();

                return json([
                    'code' => 0,
                    'msg' => '登录成功',
                    'data' => [
                        'token' => $token,
                        'expires_at' => $expiresAt,
                        'admin' => [
                            'id' => $admin['id'],
                            'username' => $admin['username'],
                            'real_name' => $admin['real_name'],
                            'email' => $admin['email'],
                            'avatar' => $admin['avatar'],
                            'role' => $admin['role']
                        ]
                    ]
                ]);

            } catch (\Exception $e) {
                return json(['code' => 1, 'msg' => '登录失败：' . $e->getMessage()]);
            }
        }

        return json(['code' => 1, 'msg' => '请求方法错误']);
    }

    /**
     * 管理员退出登录
     */
    public function logout()
    {
        $token = $this->request->header('Authorization', '');
        $token = str_replace('Bearer ', '', $token);

        if ($token) {
            // 删除会话
            Db::name('sessions')->where('token', $token)->delete();
        }

        return json(['code' => 0, 'msg' => '退出成功']);
    }

    /**
     * 验证会话
     */
    public function verify()
    {
        $token = $this->request->header('Authorization', '');
        $token = str_replace('Bearer ', '', $token);

        if (empty($token)) {
            return json(['code' => 1, 'msg' => '请先登录']);
        }

        try {
            $session = Db::name('sessions')
                ->alias('s')
                ->join('users a', 's.admin_id = a.id')
                ->where('s.token', $token)
                ->where('s.expires_at', '>', date('Y-m-d H:i:s'))
                ->where('a.status', 1)
                ->field('s.*,a.username,a.real_name,a.email,a.avatar,a.role')
                ->find();

            if (!$session) {
                return json(['code' => 1, 'msg' => '登录已过期，请重新登录']);
            }

            // 更新会话过期时间（滑动过期）
            $newExpiresAt = date('Y-m-d H:i:s', time() + 7200);
            Db::name('sessions')
                ->where('token', $token)
                ->update([
                    'expires_at' => $newExpiresAt,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

            return json([
                'code' => 0,
                'msg' => '验证成功',
                'data' => [
                    'admin' => [
                        'id' => $session['admin_id'],
                        'username' => $session['username'],
                        'real_name' => $session['real_name'],
                        'email' => $session['email'],
                        'avatar' => $session['avatar'],
                        'role' => $session['role']
                    ],
                    'expires_at' => $newExpiresAt
                ]
            ]);

        } catch (\Exception $e) {
            return json(['code' => 1, 'msg' => '验证失败：' . $e->getMessage()]);
        }
    }

    /**
     * 修改密码
     */
    public function changePassword()
    {
        $token = $this->request->header('Authorization', '');
        $token = str_replace('Bearer ', '', $token);

        // 验证会话
        $admin = $this->getAdminByToken($token);
        if (!$admin) {
            return json(['code' => 1, 'msg' => '请先登录']);
        }

        $oldPassword = input('post.old_password', '');
        $newPassword = input('post.new_password', '');
        $confirmPassword = input('post.confirm_password', '');

        // 验证参数
        if (empty($oldPassword) || empty($newPassword) || empty($confirmPassword)) {
            return json(['code' => 1, 'msg' => '所有密码字段不能为空']);
        }

        if ($newPassword !== $confirmPassword) {
            return json(['code' => 1, 'msg' => '新密码和确认密码不一致']);
        }

        if (strlen($newPassword) < 6) {
            return json(['code' => 1, 'msg' => '新密码长度不能少于6位']);
        }

        try {
            // 验证旧密码
            $adminData = Db::name('users')->find($admin['admin_id']);
            if (md5($oldPassword) !== $adminData['password']) {
                return json(['code' => 1, 'msg' => '原密码错误']);
            }

            // 更新密码
            Db::name('users')
                ->where('id', $admin['admin_id'])
                ->update([
                    'password' => md5($newPassword),
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

            // 删除该用户的所有会话（强制重新登录）
            Db::name('sessions')->where('admin_id', $admin['admin_id'])->delete();

            return json(['code' => 0, 'msg' => '密码修改成功，请重新登录']);

        } catch (\Exception $e) {
            return json(['code' => 1, 'msg' => '密码修改失败：' . $e->getMessage()]);
        }
    }

    /**
     * 生成随机令牌
     */
    private function generateToken()
    {
        return bin2hex(random_bytes(32)) . '_' . time();
    }

    /**
     * 记录登录日志
     */
    private function logLoginAttempt($username, $status, $remark, $adminId = null)
    {
        try {
            Db::name('login_logs')->insert([
                'admin_id' => $adminId ?: 0,
                'username' => $username,
                'login_ip' => $this->request->ip(),
                'login_time' => date('Y-m-d H:i:s'),
                'user_agent' => $this->request->header('User-Agent', ''),
                'status' => $status,
                'remark' => $remark
            ]);
        } catch (\Exception $e) {
            // 记录日志失败不影响主流程
        }
    }

    /**
     * 清理过期会话
     */
    private function cleanExpiredSessions()
    {
        try {
            Db::name('sessions')
                ->where('expires_at', '<', date('Y-m-d H:i:s'))
                ->delete();
        } catch (\Exception $e) {
            // 清理失败不影响主流程
        }
    }

    /**
     * 根据token获取管理员信息
     */
    private function getAdminByToken($token)
    {
        if (empty($token)) {
            return null;
        }

        try {
            return Db::name('sessions')
                ->alias('s')
                ->join('users a', 's.admin_id = a.id')
                ->where('s.token', $token)
                ->where('s.expires_at', '>', date('Y-m-d H:i:s'))
                ->where('a.status', 1)
                ->field('s.*,a.username,a.real_name,a.email,a.avatar,a.role')
                ->find();
        } catch (\Exception $e) {
            return null;
        }
    }
}